package com.ccc.javacv.db.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ccc.javacv.db.entity.DeviceVideoTask;
import com.ccc.javacv.db.mapper.DeviceVideoTaskMapper;
import com.ccc.javacv.pojo.VideoInfo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 转换任务持久化-Service实现类
 */
@Slf4j
@Service
public class DeviceVideoTaskServiceImpl implements DeviceVideoTaskService {

    /**
     * 是否开启实例化任务（入库存储）
     */
    @Value("${vediojc.task.stable.enabled:false}")
    private Boolean enabled;

    private Collection<DeviceVideoTask> data;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private DeviceVideoTaskMapper deviceVideoTaskMapper;

    /**
     * 初始化加载
     */
    @PostConstruct
    private void load() throws IOException {
        log.info("[转换任务持久化-load] 加载数据库持久化的转换任务");
        if (enabled) {
            List<DeviceVideoTask> list = deviceVideoTaskMapper.selectList(null);
            data = objectMapper.convertValue(list, new TypeReference<ConcurrentLinkedQueue<DeviceVideoTask>>() {
            });
        } else {
            data = new ConcurrentLinkedQueue<>();
        }
    }

    @PreDestroy
    public void doFlush() throws IOException {
        log.info("[转换任务持久化-doFlush]");
        // 先删除
        if (deviceVideoTaskMapper.selectCount(null) > 0) {
            deviceVideoTaskMapper.delete(null);
        }
        // 再添加
        data.forEach(deviceVideoTask -> {
            if (!exist(deviceVideoTask.getId())) {
                deviceVideoTaskMapper.insert(deviceVideoTask);
            }
        });
    }

    @Override
    public void insert(DeviceVideoTask videoInfo) {
        log.info("[转换任务持久化-insert]");
        boolean match = data.stream().anyMatch(deviceVideoTask -> deviceVideoTask.getId().equals(videoInfo.getId()));
        if (!match) {
            data.add(videoInfo);
        }
        if (!exist(videoInfo.getId())) {
            deviceVideoTaskMapper.insert(videoInfo);
        }
    }

    @Override
    public void delete(String id) {
        log.info("[转换任务持久化-delete]");
        data.removeIf(e -> Objects.equals(e.getId(), id));
        deviceVideoTaskMapper.deleteById(id);
    }

    /**
     * 手动刷新
     */
    @Override
    public void manualFlush() {
        log.info("[转换任务持久化-manualFlush]");
        try {
            doFlush();
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public List<VideoInfo> list() {
        return new ArrayList<>(data);
    }

    private boolean exist(String id) {
        LambdaQueryWrapper<DeviceVideoTask> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeviceVideoTask::getId, id);
        return deviceVideoTaskMapper.selectCount(wrapper) > 0;
    }

}
